package com.rtos.model.memory;

import com.rtos.common.ProcessStatus;
import com.rtos.model.process.PCB;
import com.rtos.model.process.Process;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @Author: biubiu0002
 * @Date: 2021-09-11 0:56
 **/
public class MemoryDispatcher {
    private MAT mat = MAT.getInstance();
    private List<PCB> pcbList = SystemMemory.getPCBList();
    private static volatile ObservableList<MATNode> observableMATNodeList = FXCollections.observableArrayList();
    private static MemoryDispatcher memoryDispatcher;

    private MemoryDispatcher() {

    }

    public static synchronized ObservableList<MATNode> getObservableMATNodeList() {
        return observableMATNodeList;
    }

    public static MemoryDispatcher getInstance() {
        if (memoryDispatcher == null) {
            memoryDispatcher = new MemoryDispatcher();
        }
        return memoryDispatcher;
    }

    /**
     * 将这块记录标记为空闲区，与相邻的空闲区合并
     *
     * @param
     * @return
     */
    public synchronized boolean free(Process process) {
        /**
         * 引用问题 引用指向的实际堆对象被修改了
         * 核心：确保free()和alloc()中 加入的matnode是同一个node
         * 尝试一: mat.getMATNode()方法返回数组中的对象，可被修改。 false
         * 尝试二：mat.getMATNode()方法 以数组中的对象为模板 new一个MatNode。 false
         * 尝试三：Process类定义MatNode成员 内存分配的时候 保存到process中 true
         */
        MATNode matNode = process.getMatNode();
        boolean pcbFree = pcbList.remove(process.getPcb());
        boolean matFree = mat.free(process);

        if (pcbFree && matFree) {
          /***
             * 删除的时候 引用被改过 删除一个新的对象 肯定也是false
             */
            if (observableMATNodeList.remove(matNode)) {
            } else {
            }
            return true;
        }
        return false;

    }


    public synchronized boolean alloc(Process process) {
        boolean alloc = mat.alloc(process);
        if(alloc){
            boolean b = SystemMemory.addPCB(process.getPcb());
            if(b){
                process.getPcb().setProcessStatus(ProcessStatus.READY);
                MATNode matNode = process.getMatNode();
                observableMATNodeList.add(matNode);
                return true;
            }
        }
        return false;


    }



}
